﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.Xml;

namespace TRAC_Demo
{
    // T.R.A.C.
    // Main Author: Ryan Redburn
    // Additional Authors: Morgan Davis
    // Date: 9/30/2013

    #region [ Updates ]

    // Updated: 10/3/2013
    // By: Ryan Redburn
    // Updates: Added a combo box for color selection,
    // combo box event that changes the forms color based on selection,
    // method to parse user selected color into a string so it can be stored in the xml doc

    // Updated: 10/5/2013
    // By: Ryan Redburn
    // Updates: Altered the CheckAgent method to be more efficient

    // Updated: 10/31/2013
    // By: Ryan Redburn
    // Updates: Changed the CreateUser() method to properly function with the changes to the AccountKeeper class,
    // changed the name of the CheckAgent() method (ValidateAgent) to properly reflect it's purpose

    #endregion

    public partial class FormCreate : Form
    {
        #region [ Fields ]

        private bool createDefault;
        private bool closeProccess;
        private string errorMessage = "";
        private string errorTitle = "";
        private int empID;

        #endregion

        #region [ Contructors ]

        public FormCreate()
        {
            InitializeComponent();
            createDefault = false;
            closeProccess = false;
        }

        // Overloaded contructor that sets up the form for the default user creation process
        public FormCreate(bool arg)
        {
            InitializeComponent();
            radAdmin.Checked = true;
            radStandard.Enabled = false;
            createDefault = arg;
            closeProccess = true;
        }

        #endregion

        #region [ Events ]

        // Shows a message on first app use
        private void FormCreate_Load(object sender, EventArgs e)
        {
            if (createDefault == true)
            {
                MessageBox.Show("The first account created will be made an administrator. On this form you will specify an admin code instead of giving one.", "Account Initialization");
            }
        }

        // Creates an account based on user selection
        private void btnCreate_Click(object sender, EventArgs e)
        {
            try
            {
                if (ValidateCreation())
                {
                    CreateUser();
                    MessageBox.Show("Your user account was created successfully.", "Account Created");
                    this.Close();
                }
                else
                {
                    MessageBox.Show(errorMessage, errorTitle);
                }
            }
            catch (SqlException)
            {
                MessageBox.Show("The given employee ID does not exist.", "Invalid Employee ID");
            }
            catch (XmlException x)
            {
                MessageBox.Show(x.Message);
            }
        }

        // Clears all text boxes
        private void btnClear_Click(object sender, EventArgs e)
        {
            txtEmpID.Clear();
            txtFirstName.Clear();
            txtLastName.Clear();
            txtUserID.Clear();
            txtPassword.Clear();
            txtRePassword.Clear();
            txtAdminCode.Clear();
        }

        // Exits app on user confirmation
        private void btnExit_Click(object sender, EventArgs e)
        {
            // Closes app
            if (closeProccess == true)
            {
                if (MessageBox.Show("Are you sure you want to exit?", "Confirm Exit",
               MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    Application.Exit();
                }
            }
            // Closes the form
            else if (closeProccess == false)
            {
                if (MessageBox.Show("Are you sure you want to exit account creation?", "Cancel Account Creation",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    this.Close();
                }
            }
        }

        // Changes the color of the create form to provide an example to the user
        private void cmbColor_SelectionChangeCommitted(object sender, EventArgs e)
        {
            string selection = (string)cmbColor.SelectedItem;
            List<int> colorValues = ColorKeeper.RetrieveColor(selection);
            this.BackColor = Color.FromArgb(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
        }

        #endregion

        #region [ Methods ]

        // Creates the xml doc on first use otherwise creates a new user
        private void CreateUser()
        {
            if (radAdmin.Checked)
            {
                AccountKeeper.CreateAdminAcct(txtUserID.Text, txtEmpID.Text, txtPassword.Text, ParseUserColor());
                if (createDefault)
                    AccountKeeper.ChangeAdminCode(txtAdminCode.Text);
            }
            else if (radStandard.Checked)
            {
                AccountKeeper.CreateStandardAcct(txtUserID.Text, txtEmpID.Text, txtPassword.Text, ParseUserColor());
            }
        }

        // Confirms that all required information has been provided
        private bool ValidateCreation()
        {
            if (radAdmin.Checked)
            {
                if (CheckTextPopulace() && CheckPasswords() && FormatEmpID())
                {
                    if (ValidateAgent(empID))
                    {
                        if (createDefault)
                        {
                            return true;
                        }
                        else
                        {
                            if (AccountKeeper.ValidateAdmin(txtAdminCode.Text))
                            {
                                return true;
                            }
                            else
                            {
                                errorMessage = "The administrator code entered does not match the one on file.";
                                errorTitle = "Invalid Administrator Code";
                                return false;
                            }
                        }
                    }
                    else
                    {
                        errorMessage = "The employee entered does not exist, or the ID and name entered do not match.";
                        errorTitle = "Invalid Employee Information";
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else if (radStandard.Checked)
            {
                if (CheckTextPopulace() && CheckPasswords() && FormatEmpID())
                {
                    if (ValidateAgent(empID))
                    {
                        return true;
                    }
                    else
                    {
                        errorMessage = "The employee entered does not exist, or the ID and name entered do not match.";
                        errorTitle = "Invalid Employee Information";
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        // Method used to verify that agent exists in the data base
        // As well as verifying agent name is assigned to that particular ID number
        private bool ValidateAgent(int empID)
        {
            bool agentValidated = false;
            TRACobjectsDataContext dataBaseConnection = new TRACobjectsDataContext();

            var myQuery = from ca in dataBaseConnection.Agents where ca.EmployeeID == empID select ca;

            foreach (var checkVar in myQuery)
            {
                if (checkVar.EmployeeID == int.Parse(txtEmpID.Text) && (checkVar.fName.Trim() == txtFirstName.Text) && (checkVar.lName.Trim() == txtLastName.Text))
                {
                    agentValidated = true;
                }
            }

            dataBaseConnection.Dispose();

            return agentValidated;
        }

        #endregion

        #region [ Helper Methods ]

        // Checks taht all text boxes are populated
        private bool CheckTextPopulace()
        {
            if (radAdmin.Checked)
            {
                if (txtUserID.Text == "" || txtPassword.Text == "" || txtRePassword.Text == "" || txtAdminCode.Text == "" || txtEmpID.Text == "" || txtFirstName.Text == "" || txtLastName.Text == "")
                {
                    errorMessage = "One or more required text fields were left empty.";
                    errorTitle = "Empty Text Fields";
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else if (radStandard.Checked)
            {
                if (txtUserID.Text == "" || txtPassword.Text == "" || txtRePassword.Text == "" || txtEmpID.Text == "" || txtFirstName.Text == "" || txtLastName.Text == "")
                {
                    errorMessage = "One or more required text fields were left empty.";
                    errorTitle = "Empty Text Fields";
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        // Checks whether or not the passwords match
        private bool CheckPasswords()
        {
            if (txtPassword.Text == txtRePassword.Text)
            {
                return true;
            }
            else
            {
                errorMessage = "Your passwords do not match.";
                errorTitle = "Invalid Password";
                return false;
            }
        }

        // Checks whether the given employee id is numeric and converts it to an int if so
        private bool FormatEmpID()
        {
            if (int.TryParse(txtEmpID.Text, out empID))
            {
                empID = int.Parse(txtEmpID.Text);
                return true;
            }
            else
            {
                return false;
            }
        }

        // Converts the chosen color value into hex
        private string ParseUserColor()
        {
            string color = "";

            if ((string)cmbColor.SelectedItem != null)
            {
                color = (string)cmbColor.SelectedItem;
            }
            else
            {
                color = "Default";
            }

            return color;
        }

        #endregion
    }
}
